# coding: utf-8
from datetime import timedelta
from typing import Union

from minio import Minio

from .._models import MinioSetting
from ..config import pytest_config


class MinioClient:
    """
    Minio class
    """

    def __init__(self, minio_setting: Union[MinioSetting, dict] = None):
        if isinstance(minio_setting, dict):
            minio_setting = MinioSetting(**minio_setting)
        if not minio_setting:
            minio_setting = pytest_config.minio_setting
        self.client = Minio(
            endpoint=minio_setting.endpoint,
            access_key=minio_setting.access_key,
            secret_key=minio_setting.secret_key,
            secure=minio_setting.secure
        )
        if not minio_setting.bucket_name:
            raise ValueError("bucket_name is required")
        self.bucket_name = minio_setting.bucket_name
        self.minio_setting = minio_setting

    def bucket_exists(self):
        """
        检查桶是否存在
        """
        return self.client.bucket_exists(self.bucket_name)

    def make_bucket(self):
        """
        创建桶
        """
        return self.client.make_bucket(self.bucket_name)

    def remove_bucket(self):
        """
        删除桶
        """
        return self.client.remove_bucket(self.bucket_name)

    def list_objects(self, prefix=None, recursive=False):
        """
        列出桶中的对象
        """
        return self.client.list_objects(self.bucket_name, prefix=prefix, recursive=recursive)

    def put_object(self, object_name, data, length=None, content_type=None, metadata=None, sse=None, progress=None):
        """
        上传对象
        """
        return self.client.put_object(self.bucket_name, object_name, data, length=length, content_type=content_type,
                                      metadata=metadata, sse=sse, progress=progress)

    def fput_object(self, object_name: str, file_path: str, content_type=None):
        """
        上传本地文件
        :param object_name:
        :param file_path:
        :param content_type:
        :return:
        """
        self.client.fput_object(self.bucket_name, object_name, file_path, content_type=content_type)

    def get_object_link(self, object_name):
        """

        :param object_name:
        :return:
        """
        return self.client.presigned_get_object(self.bucket_name, object_name,
                                                expires=timedelta(days=self.minio_setting.link_expires))

    def upload_zip(self, object_name: str, file_path: str):
        """
        上传zip文件
        :return:
        """
        print('*************上传zip文件*************')
        print(object_name, file_path)
        if not self.bucket_exists():
            self.make_bucket()
        #     application/x-zip-compressed
        self.fput_object(object_name, file_path, content_type='application/zip')
        return self.get_object_link(object_name)
